from collections import Counter
import os
import numpy as np
import pandas as pd
import random
from openpyxl import Workbook
from openpyxl.drawing.image import Image
import time

try:
    from .cvio import cvio
except:
    from cvio import cvio


def update_daily_work(xlsxpath, name):
    xlsx = pd.read_excel(xlsxpath, sheet_name=None)
    if not '日常工作表' in xlsx or not '今日统计表' in xlsx:
        print('表格中不存在"日常工作表"或"今日统计表"', xlsxpath)
        return
    zb = dict(xlsx['日常工作表'])
    xb = dict(xlsx['今日统计表'])

    for k, v in zb.items():
        zb[k] = list(v)

    for k, v in xb.items():
        xb[k] = list(v)

    for i, n in enumerate(xb['类别']):
        # 含标注图片/对
        if '含标注图片/对' in n:
            continue
        if n in zb['SKU映射名称']:
            j = zb['SKU映射名称'].index(n)
            numzb = zb['已有框数'][j]
            zb['已有框数'][j] = int(xb['数量'][i]) if 'nan' == str(
                numzb) else (int(xb['数量'][i]) + int(numzb))
            namezb = zb['标注负责人'][j]
            zb['标注负责人'][j] = name if '' == str(namezb).lower() or name == str(
                namezb).lower() or 'nan' == str(namezb).lower() else '%s%s' % (namezb, name)
            zb['更新日期'][j] = time.strftime(
                "%Y-%m-%d %H:%M:%S", time.localtime())
        else:
            zb['SKU映射名称'].append(n)
            zb['已有框数'].append(int(xb['数量'][i]))
            zb['标注负责人'].append(name)
            zb['是否有实物'].append('')
            zb['更新日期'].append(time.strftime(
                "%Y-%m-%d %H:%M:%S", time.localtime()))

    dst = os.path.join(os.path.dirname(xlsxpath), '更新后总表.xlsx')
    zbdf = pd.DataFrame(zb)
    zbdf.to_excel(dst, index=False)
    print('更新后总表保存至（%s）' % dst)

def skuCount(src, folder=False, save_dir=None):
    print('检索加载数据集.')
    if not folder:
        ann_list = cvio.load_ext_list(src, ext_type='.json', recursive=False, silent=False)
    else:
        ann_list = []
    n = len(ann_list)
    if n > 0:
        print('统计Json标注数据.')
        m = 0
        counter = dict()
        for i, ann in enumerate(ann_list, 1):
            print('[%d/%d] %.2f%%' % (i, n, i / n * 100))
            try:
                ann_info = cvio.load_ann(ann)
                shapes = ann_info['shapes']
                if not len(shapes): continue
                for shape in shapes:
                    label = shape['label']
                    if not label in counter:
                        counter[label] = 1
                    else:
                        counter[label] += 1
                m += len(shapes)
            except:
                print('Exception')
    else:
        imgs = cvio.load_image_list(src, recursive=True, silent=False)
        counter = dict()
        n = len(imgs)
        m = n
        print('统计文件夹数据.')
        for i, img in enumerate(imgs, 1):
            if i % 10000 == 0:
                print('[%d/%d] %.2f%%' % (i, n, i/n*100))
            label = img.split(os.sep)[-2]
            if not label in counter:
                counter[label] = 1
            else:
                counter[label] += 1
    if n == 0:
        print('路径(%s)下无数据.' % src)
        return
    print('[%d/%d] %.2f%%' % (i, n, i / n *100))

    xls_dic = {"类别":[], "数量":[]}
    for k, v in counter.items():
        print(k, v)
        xls_dic['类别'].append(k)
        xls_dic['数量'].append(v)
    xls_dic['类别'].append('含标注图片')
    xls_dic['数量'].append(n)
    print("含%d标注图片, %d类, %d总标注框" % (n, len(counter), m))
    if save_dir in (None, ''):
        save_dir = os.path.join(src, 'skuCount.xlsx')
    if not os.path.exists(os.path.dirname(save_dir)):
        os.makedirs(os.path.dirname(save_dir))
    try:
        pd.DataFrame(xls_dic).to_excel(
            save_dir, sheet_name='数据集统计', index=False)
    except:
        with open(save_dir, 'w') as fp:
            for k, v in counter.items():
                print(k, v, file=fp)
    finally:
        print('统计结果保存至%s.' % save_dir)

def skuCountV2(src, dst, mode='pair', recursive=False, time_limit=2):
    assert mode in ('pair', 'json', 'cuts')

    start = time.time()
    labels = []
    info = ''
    if mode == 'cuts':
        print('裁剪图模式需递归统计文件夹数据.')
        img_list = cvio.load_image_list(src, recursive=True, silent=False)
        n = len(img_list)
        for i, img in enumerate(img_list, 1):
            end = time.time()
            info = '[%d/%d] %.2f%% %s' % (i, n, i / n * 100, os.path.basename(img))
            if (end - start) >= time_limit:
                start = end
                print(info.ljust(100, ' '))
            label = img.split(os.sep)[-2]
            labels.append(label)
    else:
        if mode == 'pair':
            img_ann_list = cvio.load_img_ann_list(src, recursive=recursive, silent=False)
        elif mode == 'json':
            img_ann_list = cvio.load_ext_list(src, ext_type='.json', recursive=recursive, silent=False)
            img_ann_list = [[None, ann] for ann in img_ann_list]
        n = len(img_ann_list)
        for i, (img, ann) in enumerate(img_ann_list, 1):
            end = time.time()
            info = '[%d/%d] %.2f%% %s' % (i, n, i / n * 100, os.path.basename(ann))
            if (end - start) >= time_limit:
                start = end
                print(info.ljust(100, ' '))            
            anno = cvio.load_ann(ann)
            shapes = anno['shapes']
            labels.extend([shape['label'] for shape in shapes])
    print(info.ljust(100, ' '))            
    count = Counter(labels)
    xls_dic = {"类别":[], "数量":[]}
    for k, v in count.items():
        print(k, v)
        xls_dic['类别'].append(k)
        xls_dic['数量'].append(v)
    xls_dic['类别'].append('含标注图片')
    xls_dic['数量'].append(n)
    print("含%d标注图片, %d类, %d总标注框" % (n, len(count), len(labels)))
    if dst in (None, ''):
        dst = os.path.join(src, '%s_count.xlsx' % mode)
    if not os.path.exists(os.path.dirname(dst)):
        os.makedirs(os.path.dirname(dst))
    try:
        pd.DataFrame(xls_dic).to_excel(
            dst, sheet_name='数据集统计', index=False)
    except Exception as e:
        print(e)


def gen_label_text(src, dst, instance=False):
    img_ann_list = cvio.load_img_ann_list(src, recursive=False)
    count = []
    n = len(img_ann_list)
    m = 0
    def inst(label):
        tags = label.split('-')
        if len(tags) and tags[-1].isdigit():
            tag = '-%s' % tags[-1]
            label = label[:-len(tag)]
        return label

    for i, (img, ann) in enumerate(img_ann_list, 1):
        try:
            ann_info = cvio.load_ann(ann)
            shapes = ann_info['shapes']
            if not len(shapes):
                continue
            if instance:
                labels = [inst(shape['label']) for shape in shapes]
            else:
                labels = [shape['label'] for shape in shapes]
            count.extend(labels)
            m += len(labels)
        except:
            print('Exception')
    # print(count)
    counter = dict(Counter(count))
    
    labelIds = dict()
    labels = list(dict(counter))
    labels.sort()
    with open(dst, 'w') as fp:
        # print('ignore\nbackground',file=fp)
        # print('background',file=fp)
        for i, k in enumerate(labels, 1):
            print(k,file=fp)
            labelIds[k] = i
    
        print('\nlabelIds=%s' % str(labelIds))
        print('\nlabel=', end='')
        for i, (k, v) in enumerate(labelIds.items(), 1):
            print(k, end=',')

def inclue_chinese(string):
    """
    检查整个字符串是否包含中文
    :param string: 需要检查的字符串
    :return: bool
    """
    for ch in string:
        if u'\u4e00' <= ch <= u'\u9fff':
            return True

    return False

def countPic2XLS(cuts, xlsx=""):
    imgList = cvio.load_image_list(cuts, recursive=True, silent=False)
    cls2imgs = {}
    for img in imgList:
        label = img.split(os.sep)[-2]
        if not label in cls2imgs:
            cls2imgs[label] = [img]
        else:
            cls2imgs[label] += [img]
    
    wb = Workbook()
    ws = wb.create_sheet("SKU映射管理", 0)  # 插入到最开始的位置
    #ws = wb.active
    ws.append(['SKU名称', 'SKU图片', 'SKU数量'])
    for i, (label, imgs) in enumerate(cls2imgs.items(), 2):
        print(i - 1, label)
        try:
            sizes = [os.path.getsize(img) for img in imgs]
            index = np.argsort(sizes)[::-1][:min(10, len(sizes))]
            select = imgs[random.choice(index)]
            # select = random.choice(imgs)
            imgsize = cvio.load_img(select, mode='pil').size
            x = max(imgsize) / 128
            height, width = (imgsize[1] / x, imgsize[0] / x)
            img = Image(select)
            img.width, img.height = (width, height)
            ws.column_dimensions['B'].width = width * 0.2
            ws.row_dimensions[i].height = height * 0.8
            ws.cell(row=i, column=1, value=label)
            ws.add_image(img, 'B%d' % i)
            ws.cell(row=i, column=3, value=len(imgs))
        except:
            print(label, select, imgsize)
            continue

    if not xlsx:
        xlsx = os.path.join(cuts, '..', cuts.split(os.sep)[-1] + '.xlsx')
    if not os.path.exists(os.path.dirname(xlsx)):
        os.makedirs(os.path.dirname(xlsx))
    wb.save(xlsx)
    print('结果保存至(%s).' % xlsx)


def countPerImg(src, dst, recursive=False):
    imgann = cvio.load_img_ann_list(src, recursive=recursive, silent=False)
    if len(imgann) < 1:
        imgann = cvio.load_ext_list(src, recursive=recursive)
        imgann = [(None, ann) for ann in imgann]
    if len(imgann) < 1:
        return
        
    imShapesCount = dict(图片=[], 框数=[])
    n = len(imgann)
    for i, (img, ann) in enumerate(imgann, 1):
        print('[%d/%d] %s' % (i, n, img))
        anninfo = cvio.load_ann(ann)
        if img is not None:
            img = os.path.basename(img)
        else:
            img = os.path.basename(anninfo['imagePath'])
        if not 'shapes' in anninfo:
            print(img, 'no shapes in annotations.')
            continue
        N = len(anninfo['shapes'])
        imShapesCount['图片'] += [img]
        imShapesCount['框数'] += [N]
    if dst in (None, ''):
        dst = os.path.join(src, 'imgSkuCount.xlsx')
    if not os.path.exists(os.path.dirname(dst)):
        os.makedirs(os.path.dirname(dst))
    pd.DataFrame(imShapesCount).to_excel(dst, sheet_name='图片框数量', index=False)
    print('统计结果保存至%s.' % dst)
